;(function(window,document,undefined){

    // 全局对象，不同的layer对象共用
    var layer = {
        name: "my-layer",
        ie: function(){ //ie版本
            var agent = navigator.userAgent.toLowerCase();
            return (!!window.ActiveXObject || "ActiveXObject" in window) ? (
            (agent.match(/msie\s(\d+)/) || [])[1] || '11' //由于ie11并没有msie的标识
            ) : false;
        }(),
        index: 0,
        // 以下两项不能作为全局对象，同时弹出多个层的话最后一个会覆盖前面所有层的信息，以后修改
        end: {},
        btn: ['确定']
    };

    var _layer = window.layer;

    // 私有的核心类，实现了弹出层的定义
    var Class = function(setings){  
        var that = this;
        that.index = ++layer.index;
        that.config = $.extend({}, that.config, setings);
        document.body ? that.create() : setTimeout(function(){
            that.create();
        }, 30);
    };

    Class.pt = Class.prototype;

    //缓存常用字符
    var doms = ['my-layer','my-layer-1','my-layer-content-wrap','my-layer-close','my-layer-btn'];

    // 默认配置
    Class.pt.config = {
        title: '信息',         // 标题  
        area: 'auto',		  // 宽高  
        shade: 0.3,			  // 遮罩层透明度  
        shadeClose: false,    // 点击遮罩层是否关闭弹出层  
        offset: 'auto',		  // 偏移设置  
        fixed:true,			  // 是否固定  
        time: 0,              // 弹出层持续时间，0表示不自动关闭  
        zIndex: 19891014,
        maxWidth: 360,
		formId: ""            // 弹出层所在的表单ID，该字段是为了使验证生效，如果将弹出层直接放在body中而不在form里会导致表单验证失效
    };

    Class.pt.create = function(){
        var that = this
        ,config = that.config
        ,times = that.index
        ,content = config.content
        ,conType = typeof content === 'object'
        ,body = $('body');

        var zIndex = config.zIndex + times;
        var titype = typeof config.title === 'object';
        var titleHTML = (config.title ? '<div style="'+ (titype ? config.title[1] : '') +'">' 
                            + (titype ? config.title[0] : config.title) 
                        + '</div>' : '');

        if(config.id && $('#'+config.id)[0])  return;
        if(typeof config.area === 'string'){
            config.area = config.area === 'auto' ? ['', ''] : [config.area, ''];
        }

        config.btn = ('btn' in config) ? config.btn : layer.btn[0];

        // 1、生成html
        // 遮罩层
        var shadeHtml = ('<div class="my-layer-shade" id="my-layer-shade'+ times +'" times="'+ times +'" style="'+ ('z-index:'+ (zIndex-1) +'; background-color:'+ (config.shade[1]||'#000') +'; opacity:'+ (config.shade[0]||config.shade) +'; filter:alpha(opacity='+ (config.shade[0]*100||config.shade*100) +');') +'"></div>');
        // 弹出层
        var dialogHtml = ['<div class="my-layer" id="'+ doms[0] + times +'" times='+times+' style="z-index: '+ zIndex +'; '+ (config.area[0] != "" ? 'width:'+ config.area[0]:"") + ';'+ (config.fixed ? '' : 'position:absolute;') +'" conType="'+ (conType ? 'object' : 'string') + '">',
                            '<table>',
                                '<tbody><tr class="my-layer-top">',
                                    '<td class="my-layer-title">'+ titleHTML +'</td>',
                                    '<td class="my-layer-close btn_del">×</td>',
                                '</tr>',
                            '</tbody></table>',
                            '<table class="my-layer-content-wrap">',
                                '<tbody><tr>',
                                    '<td>',
                                        '<div class="my-layer-content" '+(config.area[1]!= "" ? 'style="height:' + config.area[1] +';"':"")+'>',
                                            conType ? '' : config.content,
                                        '</div>',
                                    '</td>',
                                '</tr>',
                            '</tbody></table>',
                            '<div class="my-layer-btm">',
                                (config.btn ? function(){
                                    var button = '';
                                    typeof config.btn === 'string' && (config.btn = [config.btn]);
                                    for(var i = 0, len = config.btn.length; i < len; i++){
                                        button += '<a href="javascript:void(0)" class="'+doms[4] + ' '+ doms[4] + '' + i +'">' + config.btn[i] + '</a>'
                                    }
                                    return button;
                                }() : ''),
                            '</div>',
                        '</div>'].join('');

        body.append(shadeHtml);
        if (config.formId.length > 0 ) {
            $("#" + config.formId).append(dialogHtml);
        }
        else {
            body.append(dialogHtml);
        }

        if(conType){
            $('#'+doms[0] + times).find('.my-layer-content').append(content);
            content.show();
        }

        that.layero = $('#'+ doms[0] + times);

        that.auto(times);

        // 2、实现相关界面逻辑
        // 定位
        that.offset();

        //坐标自适应浏览器窗口尺寸
        if(config.fixed){
            win.on('resize', function(){
                that.offset();
                (/^\d+%$/.test(config.area[0]) || /^\d+%$/.test(config.area[1])) && that.auto(times);
                config.type == 4 && that.tips();
            });
        }

        // 自动关闭
        config.time <= 0 || setTimeout(function(){
            layer.close(that.index)
        }, config.time);

        // 3、事件的绑定
        that.callback();

    };

    // 事件的绑定
    Class.pt.callback = function(){
        var that = this, layero = that.layero, config = that.config;
        if(config.success){
            config.success(layero, that.index);
        }
        
        //按钮
        layero.find('.'+ doms[4]).on('click', function(){
            var index = $(this).index();
            if(index === 0){
                if(config.yes){
                    config.yes(that.index, layero);
                } else if(config['btn1']){
                    config['btn1'](that.index, layero);
                } else {
                    layer.close(that.index);  // 默认情况下，点击后关闭弹出层
                }
            } else {
                var close = config['btn'+(index+1)] && config['btn'+(index+1)](that.index, layero);
                close === false || layer.close(that.index);   // 返回false时不关闭弹窗
            }
        });
        
        //取消
        function cancel(){
            var close = config.cancel && config.cancel(that.index, layero);
            close === false || layer.close(that.index);   // 返回false时不关闭弹窗
        }
        
        //右上角关闭回调
        layero.find('.'+ doms[3]).on('click', cancel);
        
        //点遮罩关闭
        if(config.shadeClose){
            $('#my-layer-shade'+ that.index).on('click', function(){
                layer.close(that.index);
            });
        } 

        config.end && (layer.end[that.index] = config.end);
    };

    /**
     * 计算坐标
     */
    Class.pt.offset = function(){
        var that = this, config = that.config, layero = that.layero;
        var area = [layero.outerWidth(), layero.outerHeight()];
        var type = typeof config.offset === 'object';
        that.offsetTop = (win.height() - area[1])/2;
        that.offsetLeft = (win.width() - area[0])/2;
        
        if(type){
            that.offsetTop = config.offset[0];
            that.offsetLeft = config.offset[1]||that.offsetLeft;
        } else if(config.offset !== 'auto'){
            
            if(config.offset === 't'){ //上
            that.offsetTop = 0;
            } else if(config.offset === 'r'){ //右
            that.offsetLeft = win.width() - area[0];
            } else if(config.offset === 'b'){ //下
            that.offsetTop = win.height() - area[1];
            } else if(config.offset === 'l'){ //左
            that.offsetLeft = 0;
            } else if(config.offset === 'lt'){ //左上角
            that.offsetTop = 0;
            that.offsetLeft = 0;
            } else if(config.offset === 'lb'){ //左下角
            that.offsetTop = win.height() - area[1];
            that.offsetLeft = 0;
            } else if(config.offset === 'rt'){ //右上角
            that.offsetTop = 0;
            that.offsetLeft = win.width() - area[0];
            } else if(config.offset === 'rb'){ //右下角
            that.offsetTop = win.height() - area[1];
            that.offsetLeft = win.width() - area[0];
            } else {
            that.offsetTop = config.offset;
            }
            
        }
        
        if(!config.fixed){
            that.offsetTop = /%$/.test(that.offsetTop) ? 
            win.height()*parseFloat(that.offsetTop)/100
            : parseFloat(that.offsetTop);
            that.offsetLeft = /%$/.test(that.offsetLeft) ? 
            win.width()*parseFloat(that.offsetLeft)/100
            : parseFloat(that.offsetLeft);
            that.offsetTop += win.scrollTop();
            that.offsetLeft += win.scrollLeft();
        }

        layero.css({top: that.offsetTop, left: that.offsetLeft});
    };

    //自适应
    Class.pt.auto = function(index){
        var that = this, config = that.config, layero = $('#'+ doms[0] + index);
        if(config.area[0] === '' && config.maxWidth > 0){
            //为了修复IE7下一个让人难以理解的bug，IE下absolute和fixed定位时，div的width不会自适应，依旧是100%的宽度
            if(layer.ie && layer.ie < 8 && config.btn){
                layero.width(layero.innerWidth());
            }
            layero.outerWidth() > config.maxWidth && layero.width(config.maxWidth);
        }
        var area = [layero.innerWidth(), layero.innerHeight()];
        var titHeight = layero.find(doms[1]).outerHeight() || 0;
        var btnHeight = layero.find('.'+doms[6]).outerHeight() || 0;
        function setHeight(elem){
            elem = layero.find(elem);
            elem.height(area[1] - titHeight - btnHeight - 2*(parseFloat(elem.css('padding-top'))|0));
        }
        switch(config.type){
            case 2: 
            setHeight('iframe');
            break;
            default:
            if(config.area[1] === ''){
                if(config.fixed && area[1] >= win.height()){
                area[1] = win.height();
                setHeight('.'+doms[5]);
                }
            } else {
                setHeight('.'+doms[5]);
            }
            break;
        }
        return that;
    };

    /**
     * api 关闭弹出层
     */
    layer.close = function(index){
        var layero = $('#'+ doms[0] + index);
        if(!layero[0]) return;

        var remove = function(){
            var conType = layero.attr('conType');
            if(conType === 'object'){
                layero.children().not('.my-layer-content-wrap').remove();
                var contentObj = $($('.my-layer-content').children()[0]);
                while(contentObj.parents('.my-layer').length > 0){
                    contentObj.unwrap();
                    contentObj.hide();
                }
            }
            else{
                layero[0].innerHTML = '';
                layero.remove();
            }

            typeof layer.end[index] === 'function' && layer.end[index]();
        };

        $('#my-layer-shade' + index).remove();

        remove();

        /*if(layer.ie && layer.ie < 10){
            remove()
        } else {
            setTimeout(function(){
                remove();
            }, 200);
        }*/
    };

    /**
     * api 关闭所有弹出层
     */
    layer.closeAll = function(){
        $.each($('.'+doms[0]), function(){
            var othis = $(this);
            layer.close(othis.attr('times'));
        });
    };

    /**
     * api 打开弹出层
     */
    layer.open = function(deliver){
        var o = new Class(deliver);
        return o.index;
    };

    /**
     * api 解决命名冲突
     */
    layer.noConflict = function(){
        if (window.layer === layer ) {
            window.layer = _layer;
        }
        return layer;
    };
    

    /*(function(){
        $ = window.jQuery;
        win = $(window);
        doms.html = $('html');
        layer.open = function(deliver){
            var o = new Class(deliver);
            return o.index;
        };
    })();*/

    win = $(window);

    window.layer = layer;

})(window,document);